/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package stuff.ext;

import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.context.request.NativeWebRequest;

/**
 *
 * @author Николай
 */

@Aspect
public class AspectMethodIvoker {

    private static final Logger logger = LoggerFactory.getLogger(AspectMethodIvoker.class);

    @Around(
    value="execution(" +
            "* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter." +
            "ServletHandlerMethodInvoker.createBinder(" +
                "org.springframework.web.context.request.NativeWebRequest,Object,String" +
                ")" +
                    ") && " +
            "args(request, target, objectName)",
    argNames="request, target, objectName")
    public WebDataBinder createBinder(ProceedingJoinPoint pjp, NativeWebRequest request, Object target, String objectName) throws Throwable {
        HttpServletRequest httpRequest = (HttpServletRequest)request.getNativeRequest();
        if (isJSONType(httpRequest)) {
            logger.debug("create json binder");
            return new JSONRequestDataBinder(target, objectName);
        }
        return (WebDataBinder)pjp.proceed();
    }

    @Around(
    value="execution(" +
            "* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter." +
            "ServletHandlerMethodInvoker.doBind(" +
                "org.springframework.web.bind.WebDataBinder," +
                "org.springframework.web.context.request.NativeWebRequest" +
                ")" +
                    ") && " +
            "args(binder,webRequest)",
    argNames="binder,webRequest")
    public void doBind(ProceedingJoinPoint pjp, WebDataBinder binder, NativeWebRequest webRequest)  throws Throwable {
        HttpServletRequest httpRequest = (HttpServletRequest)webRequest.getNativeRequest();
        if ((binder instanceof JSONRequestDataBinder) && isJSONType(httpRequest)) {
            JSONRequestDataBinder jsonBinder = (JSONRequestDataBinder)binder;
            logger.debug("json bind");
            jsonBinder.bind(httpRequest);
        } else {
            pjp.proceed();
        }
    }

    protected boolean isJSONType(HttpServletRequest req) {
        if ((req.getContentType() != null) && (req.getContentType().indexOf("application/json") != -1))
            return true;
        return false;
    }
}
